///@file IndexSet.h
///@brief Declaration of the class representing an IndexSet for polynomial chaos expansion
///@author Arnaud Duval
///@version 0.0
///@date 2010/04/14


#ifndef INDEXSET_H
#define INDEXSET_H

#include <assert.h>
#include <iostream>
#include "MultiIndex.h"


///@class IndexSet
///@brief Class defining an IndexSet
///An IndexSet is an array of MultiIndex
class IndexSet
{
	private:
		///@brief array of MultiIndex
		MultiIndex *set;
		///@brief number of MultiIndex in the set
		unsigned int nb;
	public:
		///@brief Default constructor
		IndexSet();
		///@brief Constructor with arguments for polynomial chaos
		IndexSet(int, int);
		///@brief Constructor with given size
		IndexSet(unsigned int);
		///@brief Copy constructor
		IndexSet(const IndexSet&);
		///@brief Copy constructor for temporary objects
		IndexSet(IndexSet*);
		///@brief Destructor
		~IndexSet();
		///@brief Overload of = operator
		IndexSet& operator=(const IndexSet &);
		///@brief Overload of = operator for temporary object
		IndexSet& operator=(IndexSet*);
		///@brief Cardinality of set
		int Cardinality();
		///@brief Overload of [] operator : direct access to a MultiIndex
		MultiIndex& operator[](unsigned int) const;
		///@brief Return a subset I_i set of multi index, which i-th component is not zero
		IndexSet I_i(unsigned int);
		///@brief Remove a MultiIndex
		void Remove(unsigned int);
		///@brief Make a truncation from q-norm
		void Truncate_qNorm(unsigned int, double);
		///@brief Make a truncation from qw-norm
		void Truncate_qwNorm(unsigned int, double, Vector);

		///@brief Overload of << operator
		friend std::ostream& operator<<(std::ostream &, const IndexSet&);
		///@brief Overload of + operator : add an IndexSet to another one
		friend IndexSet operator+(const IndexSet&, const IndexSet&);
		///@brief Overload of - operator : remove an IndexSet from another one
		friend IndexSet operator-(const IndexSet&, const IndexSet&);
};

#endif
